package com.bigfans.catalogservice.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.bigfans.framework.aspect.DynamicDataSourceAspect;
import com.bigfans.framework.dao.DynamicDataSource;
import com.bigfans.framework.event.EventRepository;
import com.bigfans.framework.event.JdbcEventRepository;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig implements EnvironmentAware {

	private static final String MYBATIS_MAPPER_LOCATION = "classpath:mybatis/mapper/*-Mapper.xml";
	private static final String MYBATIS_CONFIG_LOCATION = "classpath:mybatis/MybatisConfig.xml";

	private Environment env;

	@Override
	public void setEnvironment(Environment env) {
		this.env = env;
	}

	/**
	 * 主库配置
	 */
	@Bean(name = "masterDataSource")
	public DataSource createMasterDataSource() throws Exception {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(env.getProperty("master.datasource.driverClassName"));
		dataSource.setUrl(env.getProperty("master.datasource.url"));
		dataSource.setUsername(env.getProperty("master.datasource.username"));
		dataSource.setPassword(env.getProperty("master.datasource.password"));
		dataSource.setTestWhileIdle(true);
		return dataSource;
	}
	
	/**
	 * 从库配置
	 */
	@Bean(name = "clusterDataSource1")
	public DataSource createCluster1DataSource() throws Exception {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(env.getProperty("cluster1.datasource.driverClassName"));
		dataSource.setUrl(env.getProperty("cluster1.datasource.url"));
		dataSource.setUsername(env.getProperty("cluster1.datasource.username"));
		dataSource.setPassword(env.getProperty("cluster1.datasource.password"));
		dataSource.setTestWhileIdle(true);
		return dataSource;
	}

	@Bean(name = "dynamicDataSource")
	@Primary
	public DataSource createDynamicDataSource(
			@Qualifier("masterDataSource") DataSource masterDataSource ,
			@Qualifier("clusterDataSource1") DataSource clusterDataSource1){
		DynamicDataSource dynamicDataSource = new DynamicDataSource();
		dynamicDataSource.putMaster(masterDataSource);
		dynamicDataSource.putCluster(clusterDataSource1);
		dynamicDataSource.setTargetDataSources();
		return dynamicDataSource;
	}

	@Bean(name = "transactionManager")
	public DataSourceTransactionManager createTransactionManager(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) throws Exception {
		return new DataSourceTransactionManager(dynamicDataSource);
	}

	@Bean(name = "sqlSessionFactory")
	public SqlSessionFactory masterSqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource)
			throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(dynamicDataSource);
		ResourcePatternResolver pathResolver = new PathMatchingResourcePatternResolver();
		sessionFactory.setConfigLocation(pathResolver.getResource(MYBATIS_CONFIG_LOCATION));
		sessionFactory.setMapperLocations(pathResolver.getResources(MYBATIS_MAPPER_LOCATION));
		return sessionFactory.getObject();
	}

	@Bean
	public DynamicDataSourceAspect dynamicDataSourceAspect(){
		return new DynamicDataSourceAspect();
	}

	@Bean
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory){
		return new SqlSessionTemplate(sqlSessionFactory);
	}

	@Bean
	public JdbcTemplate jdbcTemplate(@Qualifier("dynamicDataSource") DataSource dynamicDataSource){
		return new JdbcTemplate(dynamicDataSource);
	}

	@Bean
	public TransactionTemplate transactionTemplate(@Qualifier("dynamicDataSource") DataSource dynamicDataSource){
		PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dynamicDataSource);
		TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
		return transactionTemplate;
	}
}
